import { rmSync, createWriteStream } from 'fs'
import { exec } from 'child_process'
import axios from 'axios'
import unzipper from 'unzipper'
import { join } from 'path'
import global from './global'
import { mkdir } from 'fs/promises'
import { promisify } from 'util'
import log from 'electron-log'

export default class globalPublic {
  // 封装 exec 函数，返回执行是否成功的布尔值
  public static async executeCommand(command: string, isPrint: boolean = true): Promise<boolean> {
    if (isPrint) log.info('command', command)
    return new Promise((resolve) => {
      exec(command, (error) => {
        if (error) {
          log.error(`执行命令出错: ${error}`)
          resolve(false)
        } else {
          resolve(true)
        }
      })
    })
  }

  // 删除指定文件/文件夹
  static async delFile(filePath: string) {
    try {
      rmSync(filePath, { recursive: true, force: true })
      log.info(`文件夹删除成功: ${filePath}`)
    } catch (err: any) {
      log.error(`删除文件夹失败: ${err.message}`)
    }
  }

  // 解压文件
  static async unzipFile(zipFilePath: string, extractPath: string) {
    try {
      global.mainWindow?.webContents.send('change-loading-text', '拼多多下载完成，解压中...')
      await unzipper.Open.file(zipFilePath).then((d) => d.extract({ path: extractPath }))
      global.mainWindow?.webContents.send('change-loading', false)
      this.delFile(zipFilePath)
      log.info(`文件解压成功到: ${extractPath}`)
    } catch (err) {
      log.error(`文件解压失败: ${err}`)
    }
  }

  // 下载并解压文件
  static async downloadAndUnzip() {
    const downloadDir = join(global.localPath, 'pdd', '3.4.0.16')
    try {
      // 创建下载目录
      await mkdir(downloadDir, { recursive: true })
      const response = await axios.get('https://oss.wengekefu.com/pddWorkbench.zip', {
        responseType: 'stream',
        // 监听下载进度
        onDownloadProgress: (progressEvent) => {
          const totalLength = progressEvent.lengthComputable
            ? progressEvent.total
            : progressEvent.loaded
          if (totalLength) {
            const percent = Math.round((progressEvent.loaded * 100) / totalLength)
            log.info(`下载进度: ${percent}%`)

            if (percent === 100) {
              log.info('下载完成')
              const zipFilePath = join(downloadDir, 'pddWorkbench.zip')
              this.unzipFile(zipFilePath, downloadDir)
            }
          }
        }
      })
      // 使用传入的下载目录
      const savePath = join(downloadDir, 'pddWorkbench.zip')
      const writer = createWriteStream(savePath)

      response.data.pipe(writer)
    } catch (err) {
      log.error(`文件下载失败: ${err}`)
    }
  }

  //通过进程名称找到进程pid
  static async getPidByName(processName: string) {
    try {
      // 构建 tasklist 命令，以 CSV 格式输出且不包含标题行
      const command = `tasklist /fi "imagename eq ${processName}" /fo csv /nh`
      // 这里原代码有误，exec 应使用 util.promisify 转为 Promise 形式
      const { stdout } = await promisify(exec)(command)
      // 将输出按行分割
      const lines = stdout.trim().split('\n')
      if (lines.length >= 1) {
        // 提取第一行的 PID 部分
        const [, pid] = lines[0].split(',')
        return parseInt(pid.replace(/"/g, ''), 10) // 去除可能存在的引号
      }
      return null
    } catch (error) {
      log.error(`获取进程PID失败: ${error}`)
      return null
    }
  }

  //下载并解压inject
  static async downloadAndUnzipInject() {
    let command: string = `if exist "${join(global.injectPath, 'Launch.exe')}" (exit 0) else (exit 1)`

    const result = await this.executeCommand(command, false)
    if (result) return
    try {
      // 创建下载目录
      await mkdir(global.injectPath, { recursive: true })
      const response = await axios.get('https://oss.wengekefu.com/inject.zip', {
        responseType: 'stream'
      })
      // 使用传入的下载目录
      const savePath = join(global.injectPath, 'inject.zip')
      const writer = createWriteStream(savePath)

      // 使用 pipeline 确保下载完成
      await new Promise((resolve, reject) => {
        response.data.pipe(writer)
        response.data.on('end', resolve)
        response.data.on('error', reject)
      })

      log.info('下载完成')
      const zipFilePath = join(global.injectPath, 'inject.zip')
      await this.unzipFile(zipFilePath, global.injectPath)
    } catch (err) {
      log.error(`文件下载失败: ${err}`)
    }
  }
}
